#ifndef CLASSID_H_INCLUDED
#define CLASSID_H_INCLUDED

#include "types.h"

#define DECLARE_CLASSID(class) \
    static ClassId* sClassId; \
    static Instance* sNew(const string& name = "Untitled", ClassId* classId = sClassId) { return new class(name, classId); }

#define DEFINE_CLASSID(class, name, extension, parent) \
    ClassId* class::sClassId = new ClassId(name, extension, parent, class::sNew);

class ClassId
{
    public:
        ClassId(const string& name, const string& extension, ClassId* parent, Instance*(*allocate)(const string&,ClassId*));
        virtual ~ClassId();

        virtual string getPathName();
        virtual Uint32 getHash();

        static ClassId* getFromPathName(const string& pathname);
        static ClassId* getFromHash(Uint32 hash);

        virtual string getExtension() { return mExtension; }

        virtual Instance* allocate(const string& name, ClassId* classId);

    private:
        static tree<ClassId*> sHierarchy;

        string mName;
        string mExtension;
        tree<ClassId*>::iterator mRank;

        Instance* (*mAllocate)(const string&, ClassId*);
};

#endif // CLASSID_H_INCLUDED
